//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Drawing;

namespace Microsoft.Research.DataLayer
{
    partial class Namespace
    {
        public const string RootName = "Root";
        public const string WorkflowRootName = "Workflow";
        public const string UncategorizedName = "Uncategorized";
        public const string WorkflowTagsName = "Designer Tags";

        protected override void OnConstructor()
        {
            base.OnConstructor();

            this.Children.OnAfterInsert += new SyncCollection<Namespace, Namespace>.AfterInsertCallback(Children_OnAfterInsert);
        }

        void Children_OnAfterInsert(object sender, Namespace newItem)
        {
            // Update parent reference
            newItem.Parent = this;
        }

        public void CascadeDelete()
        {
            foreach (Namespace ns in Children)
            {
                // Cascade delete all child nodes
                ns.CascadeDelete();
            }

            // Updates child to remove deleted nodes
            Children.Refresh();

            foreach (NamespaceIconBlob nsBlob in this.IconStores)
            {
                nsBlob.Delete();
            }

            this.IconStores.Refresh();

            // Delete itself
            Delete();
        }

        private List<object> tempAct = new List<object>();
        public List<object> Activities
        {
            get { return tempAct; }
        }

        public override string ToString()
        {
            return string.Format("Namespace='{0}'", this.Name ?? "");
        }

        /// <summary>
        /// Retrieve workflows from a category.
        /// </summary>
        /// <param name="workflowName">workfow name.</param>
        /// <returns>List of workflows.</returns>
        public Collection<Activity> GetWorkflows(string workflowName)
        {
            #region Validation of Arguments
            if (string.IsNullOrEmpty(workflowName))
            {
                throw new ArgumentNullException("workflowName");
            }
            #endregion
            Collection<Activity> activities = null;
            try
            {
                Activity.ISearch.ISearchClause categorySearchClause = Activity.ISearch.Namespace(RelationFieldBase.Condition.Equals, this);
                Activity.ISearch.ISearchClause nameSearchClause = Activity.ISearch.Name(StringField.Condition.Equals, workflowName);
                Activity.ISearch.ISearchClause deletedSearchClause = Activity.ISearch.IsDeleted(BooleanField.Condition.Equals, false);
                Activity.ISearch search = Activity.ISearch.Create();
                search.Query = Activity.ISearch.AND(categorySearchClause, nameSearchClause, deletedSearchClause);
                activities = new Collection<Activity>(Activity.Search(search, this.Conn));
            }
            catch (RecordNotFoundException)
            {

            }
            return activities;
        }

        /// <summary>
        /// Retrieve workflows from a category.
        /// </summary>
        /// <param name="workflowName">workfow name.</param>
        /// <param name="label">workflow label.</param>
        /// <returns>List of workflows.</returns>
        public Collection<Activity> GetWorkflows(string workflowName, string label)
        {
            #region Validation of Arguments
            if (string.IsNullOrEmpty(workflowName))
            {
                throw new ArgumentNullException("workflowName");
            }
            if (string.IsNullOrEmpty(label))
            {
                throw new ArgumentNullException("label");
            }
           #endregion
            Collection<Activity> activities = null;
            try
            {
                Activity.ISearch.ISearchClause categorySearchClause = Activity.ISearch.Namespace(RelationFieldBase.Condition.Equals, this);
                Activity.ISearch.ISearchClause nameSearchClause = Activity.ISearch.Name(StringField.Condition.Equals, workflowName);
                Activity.ISearch.ISearchClause labelSearchClause = Activity.ISearch.VersionLabel(StringField.Condition.Equals, label);
                Activity.ISearch.ISearchClause deletedClause = Activity.ISearch.IsDeleted(BooleanField.Condition.Equals, false);
                Activity.ISearch search = Activity.ISearch.Create();
                search.Query = Activity.ISearch.AND(categorySearchClause, nameSearchClause, labelSearchClause, deletedClause);
                activities = new Collection<Activity>(Activity.Search(search, this.Conn));
            }
            catch (RecordNotFoundException)
            {

            }
            return activities;
        }
        #region CommonSearches
        public sealed class CommonSearches
        {
            private CommonSearches()
            {
            }

            /// <summary>
            /// Retreives namespaces by name. 
            /// </summary>
            /// <param name="name">The namespace name.</param>
            /// <param name="connection">The registry connection.</param>
            /// <returns>Collection of namespaces.</returns>
            public static Collection<Namespace> GetNamespaceByName(string name, Connection connection)
            {
                #region Validation of Arguments
                if (null == connection)
                {
                    throw new ArgumentNullException("connection");
                }
                if (string.IsNullOrEmpty(name))
                {
                    throw new ArgumentNullException("name");
                }
                #endregion


                Collection<Namespace> availableNamespaces = null;
                try
                {
                    Namespace.ISearch searchQuery = Namespace.ISearch.Create();
                    searchQuery.Query = Namespace.ISearch.Name(StringField.Condition.Equals, name);
                    availableNamespaces = new Collection<Namespace>(Namespace.Search(searchQuery, connection));
                }
                catch (RecordNotFoundException)
                {
                }
                return availableNamespaces;
            }
        }
        #endregion
    }
}
